package aliyun.cx.admin.service.impl;

import aliyun.cx.admin.entity.Role;
import aliyun.cx.admin.entity.UserRole;
import aliyun.cx.admin.mapper.RoleMapper;
import aliyun.cx.admin.mapper.UserRoleMapper;
import aliyun.cx.admin.service.UserRoleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户角色关联服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {

    private final RoleMapper roleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignRoles(Long userId, List<Long> roleIds) {
        try {
            // 先删除用户现有的角色关联
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            remove(wrapper);
            
            // 添加新的角色关联
            if (roleIds != null && !roleIds.isEmpty()) {
                // 逐个插入，避免复合主键问题
                for (Long roleId : roleIds) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    save(userRole);
                }
            }
            
            log.info("为用户分配角色成功，用户ID: {}, 角色数量: {}", userId, roleIds != null ? roleIds.size() : 0);
            return true;
        } catch (Exception e) {
            log.error("为用户分配角色失败，用户ID: {}", userId, e);
            throw new RuntimeException("分配角色失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeRoles(Long userId, List<Long> roleIds) {
        try {
            if (roleIds == null || roleIds.isEmpty()) {
                return true;
            }
            
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            wrapper.in("role_id", roleIds);
            
            boolean result = remove(wrapper);
            log.info("移除用户角色成功，用户ID: {}, 移除角色数量: {}", userId, roleIds.size());
            return result;
        } catch (Exception e) {
            log.error("移除用户角色失败，用户ID: {}", userId, e);
            throw new RuntimeException("移除角色失败", e);
        }
    }

    @Override
    public List<Long> getRoleIdsByUserId(Long userId) {
        try {
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            List<UserRole> userRoles = list(wrapper);
            
            return userRoles.stream()
                .map(UserRole::getRoleId)
                .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取用户角色ID失败，用户ID: {}", userId, e);
            return List.of();
        }
    }

    @Override
    public List<Long> getUserIdsByRoleId(Long roleId) {
        try {
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("role_id", roleId);
            List<UserRole> userRoles = list(wrapper);
            
            return userRoles.stream()
                .map(UserRole::getUserId)
                .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取角色用户ID失败，角色ID: {}", roleId, e);
            return List.of();
        }
    }

    @Override
    public boolean hasRole(Long userId, Long roleId) {
        try {
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            wrapper.eq("role_id", roleId);
            return count(wrapper) > 0;
        } catch (Exception e) {
            log.error("检查用户是否具有角色失败，用户ID: {}, 角色ID: {}", userId, roleId, e);
            return false;
        }
    }

    @Override
    public boolean hasRoleName(Long userId, String roleName) {
        try {
            // 先根据角色名称查找角色
            QueryWrapper<Role> roleWrapper = new QueryWrapper<>();
            roleWrapper.eq("name", roleName);
            Role role = roleMapper.selectOne(roleWrapper);
            
            if (role == null) {
                return false;
            }
            
            // 检查用户是否具有该角色
            return hasRole(userId, role.getId());
        } catch (Exception e) {
            log.error("检查用户是否具有角色名称失败，用户ID: {}, 角色名称: {}", userId, roleName, e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean clearUserRoles(Long userId) {
        try {
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            boolean result = remove(wrapper);
            log.info("清除用户所有角色成功，用户ID: {}", userId);
            return result;
        } catch (Exception e) {
            log.error("清除用户所有角色失败，用户ID: {}", userId, e);
            throw new RuntimeException("清除用户角色失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean clearRoleUsers(Long roleId) {
        try {
            QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
            wrapper.eq("role_id", roleId);
            boolean result = remove(wrapper);
            log.info("清除角色所有用户成功，角色ID: {}", roleId);
            return result;
        } catch (Exception e) {
            log.error("清除角色所有用户失败，角色ID: {}", roleId, e);
            throw new RuntimeException("清除角色用户失败", e);
        }
    }
}